package thread.producerconsumer;

/**
 * 生产者 和 消费者 有三个实现方式
 * put 如果满了阻塞
 * take 没有就阻塞
 */
public class ProducerConsumerDemo {

  public static void main(String[] args) {
    Store store = new Store(10);

    ProducerConsumerDemo producer = new ProducerConsumerDemo();

    Thread p1 = new Thread(new Runnable() {
      @Override
      public void run() {
        for (int i = 0; i < 10; i++) {
          try {
            Thread.sleep(100);
          } catch (InterruptedException e) {
            e.printStackTrace();
          }
          producer.proude(store);
        }
      }
    });

    Thread p2 = new Thread(new Runnable() {
      @Override
      public void run() {
        for (int i = 0; i < 10; i++) {
          try {
            Thread.sleep(100);
          } catch (InterruptedException e) {
            e.printStackTrace();
          }
          producer.proude(store);
        }
      }
    });


    Thread c1 = new Thread(new Runnable() {
      @Override
      public void run() {
        for (int i = 0; i < 10; i++) {
          producer.consumer(store);
        }
      }
    });

    Thread c2 = new Thread(new Runnable() {
      @Override
      public void run() {
        for (int i = 0; i < 10; i++) {
          producer.consumer(store);
        }

      }
    });


    c1.start();
    c2.start();

    p1.start();
    p2.start();

  }

  public static class Store {
    volatile int sig = 0;
    volatile int maxSize = 0;

    public Store(int maxSize) {
      this.maxSize = maxSize;
    }
  }

  public void proude(Store store) {
    synchronized (store) {
      while (store.sig >= store.maxSize) {
        try {
          store.wait();
        } catch (InterruptedException e) {
          e.printStackTrace();
        }
      }
      store.sig++;
      System.out.println(Thread.currentThread().getName() + "生产");
      store.notifyAll();

    }
  }

  public void consumer(Store store) {
    synchronized (store) {
      while (store.sig <= 0) {
        try {
          store.wait();
        } catch (InterruptedException e) {
          e.printStackTrace();
        }
      }
      store.sig--;
      System.out.println(Thread.currentThread().getName() + "消费");
      store.notifyAll();

    }

  }

}
